/**
 * 被代理对象 target 映射 target 下的 属性名列表 ，映射关联此属性名的副作用函数集合
 */
const targetMappingFieldKeyMappingEffectFunctionList = new WeakMap<Object, Map<String, Set<Function>>>()

// @ts-ignore
let activeEffect: Function | null = null





// @ts-ignore
const proxyHandler: ProxyHandler<Object> = {
    set(target: Object, key: string, newValue: Object): boolean {

        // @ts-ignore
        target[key] = newValue

        let fieldMap: Map<String, Set<Function>> | undefined = targetMappingFieldKeyMappingEffectFunctionList.get(target);

        if (!fieldMap) {
            return true
        }

        let targetKeyEffectFunctions: Set<Function> | undefined = fieldMap.get(key);

        if (targetKeyEffectFunctions) {
            targetKeyEffectFunctions.forEach(fn => {
                fn()
            })
        }
        return true
    },
    get(target: Object, key: string): any {
        let fieldMap = targetMappingFieldKeyMappingEffectFunctionList.get(target)

        if (!fieldMap) {
            targetMappingFieldKeyMappingEffectFunctionList.set(target, (fieldMap = new Map<String, Set<Function>>()))
        }
        let effectFnList = fieldMap.get(key);
        if (!effectFnList) {
            fieldMap.set(key, (effectFnList = new Set<Function>()))
        }
        if (activeEffect) {
            effectFnList.add(activeEffect)
        }
        // @ts-ignore
        return target[key]
    }
}
interface Data {
    a: String,
    b: String,
    c: String
}

const data: Data = {
    a: "A",
    b: "B",
    c: "C"
}

const obj: Data = new Proxy(data, proxyHandler) as Data


// @ts-ignore
function effect(fn: Function) {
    activeEffect = fn
    fn()
    activeEffect = null
}

effect(() => {
    console.log("fn1 监听 a", obj.a)
})

effect(() => {
    console.log("fn2 监听 b", obj.b)
})

effect(() => {
    console.log("fn3 监听 c", obj.c)
})


obj.a = "全新大A"

obj.b = "更新后的B"

obj.c = "崭新的C"
